package zhoufu.sz.sanxiao_check.net;

import android.content.Context;
import android.os.Parcel;
import android.os.Parcelable;
import android.support.annotation.NonNull;
import android.text.TextUtils;
import com.google.gson.Gson;
import com.google.gson.annotations.Expose;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import rx.Observable;
import rx.Subscriber;
import rx.Subscription;
import rx.functions.Action1;
import rx.functions.Func1;
import rx.schedulers.Schedulers;
import zhoufu.sz.sanxiao_check.inject.RetrofitQualifier;
import zhoufu.sz.sanxiao_check.models.BaseModel;
import zhoufu.sz.sanxiao_check.models.CheckItemModel;
import zhoufu.sz.sanxiao_check.models.DangerModel;
import zhoufu.sz.sanxiao_check.models.User;
import zhoufu.sz.sanxiao_check.utils.DESUtil;

/**
 * Created by hyc on 16-8-5.
 * 项目 ： XTSanXiao_V2
 * 开发 ： hyc
 * 时间 ： 16-8-5 上午11:47
 * 功能 ： 按顺序  上传图片,拿到上传地址后  更新数据到服务器
 */
public class ModifyActionRepository extends RequestRepository
{

    private final static String _UPIMGFINISHED = "UpImgFinished";

    public ModifyActionRepository(Context Context, @RetrofitQualifier Gson gson)
    {
        super(Context, gson);
    }

    /**
     * http://120.31.131.105:8091/WebService/WangGeTwo.asmx
     * InsertExamine
     * <p>
     * 添加安全检查信息
     * SID:场所ID
     * UserID:检查人ID
     * Complete_Time:整改完成时间
     * Remark:负责人签字
     * Remark2:检查人签字
     * Evidence:取证
     * Dangers:隐患信息 Json子集{
     * Item_ID:检查项目,
     * Before_Imgs:整改前图片集合{FilePathe:图片路径,Describe:图片描述},
     * Applying_Imgs:整改后图片集合{FilePathe:图片路径,Describe:图片描述},
     * DisposeStatus:整改状态 0：未处理 1:已整改,
     * Item_ContentCheck:隐患项内内容 1：木质 2 ：铁质 3：水泥 4 ：其他
     * }
     */

    public static class ImageEntity implements Serializable
    {
        @Expose
        String FilePathe;
        @Expose
        String Describe;
    }

    public static class Dangers implements Parcelable
    {
        @Expose
        int               Item_ID;
        @Expose
        List<ImageEntity> Before_Imgs;
        @Expose
        List<ImageEntity> Applying_Imgs;
        @Expose
        int               DisposeStatus;
        @Expose
        int               Item_ContentCheck;

        public Dangers()
        {

        }

        protected Dangers(Parcel in)
        {
            Item_ID = in.readInt();
            DisposeStatus = in.readInt();
            Item_ContentCheck = in.readInt();
        }

        public static final Creator<Dangers> CREATOR = new Creator<Dangers>()
        {
            @Override
            public Dangers createFromParcel(Parcel in)
            {
                return new Dangers(in);
            }

            @Override
            public Dangers[] newArray(int size)
            {
                return new Dangers[size];
            }
        };

        @Override
        public int describeContents()
        {
            return 0;
        }

        @Override
        public void writeToParcel(Parcel dest, int flags)
        {
            dest.writeInt(Item_ID);
            dest.writeInt(DisposeStatus);
            dest.writeInt(Item_ContentCheck);
        }
    }

    private void temp(final CheckItemModel itemModel, final RequestCallBack callBack)
    {
        upApplyImgs(itemModel).subscribe(new Subscriber<CheckItemModel>()
        {
            @Override
            public void onCompleted()
            {

            }

            @Override
            public void onError(Throwable e)
            {
                callBack.onPullFailud(e);
            }

            @Override
            public void onNext(CheckItemModel s)
            {
                System.out.println("s = " + s);
                upModifyImgs(s).subscribe(new Action1<CheckItemModel>()
                {
                    @Override
                    public void call(CheckItemModel s)
                    {
                        System.out.println("s = [" + s + "]");
                        upRemarks(s).subscribe(new Action1<CheckItemModel>()
                        {
                            @Override
                            public void call(CheckItemModel s)
                            {
                                Observable.just(s).map(new Func1<CheckItemModel, String>()
                                {
                                    @Override
                                    public String call(CheckItemModel itemModel)
                                    {
                                        List<Dangers> dangers = getDangerses(itemModel);

                                        HashMap<String, Object> build = _mapBuilder
                                                .creatationHashMap()
                                                .SID(itemModel.getSID())
                                                .UserID(User.readUser().getID())
                                                .Complet_Time(itemModel.getComplete_Time())
                                                .Remark(itemModel.getRemark())
                                                .Remark2(itemModel.getRemark2())
                                                .Evidence(itemModel.getEvidence())
                                                .Dangers(dangers)
                                                .build();
                                        return DESUtil.EncryptAsToMap(build);
                                    }
                                }).map(new Func1<String, Observable<String>>()
                                {
                                    @Override
                                    public Observable<String> call(String s)
                                    {
                                        //拿到 要上传的数据
                                        return getStringObservable(s, "InsertExamine");
                                    }
                                }).doOnNext(new Action1<Observable<String>>()
                                {
                                    @Override
                                    public void call(Observable<String> stringObservable)
                                    {
                                        addSubscribe(subChainWithCallBack(stringObservable,
                                                BaseModel.class, callBack));
                                    }
                                }).subscribeOn(Schedulers.io()).subscribe();
                            }
                        });
                    }
                });
            }
        });
    }

    public void update(final CheckItemModel itemModel, final RequestCallBack callback)
    {
        temp(itemModel, callback);
    }

    //    private Subscription upData(final CheckItemModel itemModel, final RequestCallBack callback) {
    //        Observable<String> insertExamine = Observable.zip(upRemarks(itemModel), upApplyImgs(itemModel), upModifyImgs(itemModel), new Func3<String, CheckItemModel, CheckItemModel, String>() {
    //            @Override
    //            public String call(String s, CheckItemModel itemModel, CheckItemModel itemModel2) {
    //
    //                List<Dangers> dangers = getDangerses(itemModel);
    //
    //                HashMap<String, Object> build = _mapBuilder.creatationHashMap().SID(itemModel.getSID()).UserID(itemModel.getUserID())
    //                        .Complet_Time(itemModel.getComplete_Time()).Remark(itemModel.getRemark())
    //                        .Remark2(itemModel.getRemark2()).Evidence(itemModel.getEvidence()).Dangers(dangers).build();
    //
    //                return DESUtil.EncryptAsToMap(build);
    //            }
    //        }).switchMap(new Func1<String, Observable<String>>() {
    //            @Override
    //            public Observable<String> call(String s) {
    //                return getStringObservable(s, "InsertExamine");
    //            }
    //        });
    //        return addSubscribe(subChainWithCallBack(insertExamine,BaseModel.class,callback));
    //    }

    //    private Subscription tttt(final CheckItemModel itemModel, final RequestCallBack callback) {
    //        return upApplyImgs(itemModel).map(new Func1<String, Observable<String>>() {
    //            @Override
    //            public Observable<String> call(String s) {
    //                return upRemarks(itemModel);
    //            }
    //        }).map(new Func1<Object, Observable<String>>() {
    //            @Override
    //            public Observable<String> call(Object o) {
    //                return upModifyImgs(itemModel);
    //            }
    //        }).map(new Func1<Observable<String>, String>() {
    //            @Override
    //            public String call(Observable<String> o) {
    //
    //                List<Dangers> dangers = getDangerses(itemModel);
    //
    //                HashMap<String, Object> build = _mapBuilder.creatationHashMap().SID(itemModel.getSID()).UserID(itemModel.getUserID())
    //                        .Complet_Time(itemModel.getComplete_Time()).Remark(itemModel.getRemark())
    //                        .Remark2(itemModel.getRemark2()).Evidence(itemModel.getEvidence()).Dangers(dangers).build();
    //
    //                return DESUtil.EncryptAsToMap(build);
    //            }
    //        }).map(new Func1<String, Observable<String>>() {
    //            @Override
    //            public Observable<String> call(String s) {
    //                //拿到 要上传的数据
    //
    //                return getStringObservable(s, "InsertExamine");
    //            }
    //        }).doOnNext(new Action1<Observable<String>>() {
    //            @Override
    //            public void call(Observable<String> stringObservable) {
    //                addSubscribe(subChainWithCallBack(stringObservable, BaseModel.class, callback));
    //            }
    //        }).subscribeOn(Schedulers.io()).subscribe();
    //    }

    @NonNull
    private List<Dangers> getDangerses(CheckItemModel itemModel)
    {
        List<Dangers>     dangers         = new ArrayList<>();
        Dangers           danger;
        List<DangerModel> dangerModelList = itemModel.getDangers();
        for (DangerModel model : dangerModelList)
        {
            danger = new Dangers();
            List<DangerModel.BeforeImgsEntity> imgs = model.getApplying_Imgs();
            List<ImageEntity>                  ies  = new ArrayList<>();
            if ( imgs != null )
            {
                for (DangerModel.BeforeImgsEntity img : imgs)
                {
                    if ( img == null || TextUtils.isEmpty(img.getImg()) )
                    {
                        continue;
                    }

                    ImageEntity object = new ImageEntity();
                    object.FilePathe = img.getImg();
                    object.Describe = img.getDescribe();
                    ies.add(object);
                }
            }

            danger.Applying_Imgs = ies;
            imgs = model.getBefore_Imgs();
            ies = new ArrayList<>();
            if ( imgs != null )
            {
                for (DangerModel.BeforeImgsEntity img : imgs)
                {
                    if ( img == null || TextUtils.isEmpty(img.getImg()) )
                    {
                        continue;
                    }
                    ImageEntity object = new ImageEntity();
                    object.FilePathe = img.getImg();
                    object.Describe = img.getDescribe();
                    ies.add(object);
                }
            }
            danger.Before_Imgs = ies;


            danger.DisposeStatus = model.getDisposeStatus();
            danger.Item_ContentCheck = model.getItem_ContentCheck();
            danger.Item_ID = model.getID();
            if ( danger.Applying_Imgs == null || danger.Applying_Imgs.size() == 0 && (
                    danger.Before_Imgs == null || danger.Before_Imgs.size() == 0 ) )
            {
                continue;
            }

            dangers.add(danger);
        }
        return dangers;
    }

    private Subscription getSubscription(final CheckItemModel itemModel,
            final RequestCallBack callback)
    {
        return upEveryImg(itemModel).map(new Func1<String, String>()
        {
            @Override
            public String call(String s)
            {

                if ( !TextUtils.equals(s, _UPIMGFINISHED) )
                {
                    return null;
                }
                List<Dangers> dangers = getDangerses(itemModel);

                HashMap<String, Object> build = _mapBuilder.creatationHashMap()
                        .SID(itemModel.getSID()).UserID(itemModel.getUserID())
                        .Complet_Time(itemModel.getComplete_Time()).Remark(itemModel.getRemark())
                        .Remark2(itemModel.getRemark2()).Evidence(itemModel.getEvidence())
                        .Dangers(dangers).build();

                return DESUtil.EncryptAsToMap(build);
            }
        }).filter(new Func1<String, Boolean>()
        {
            @Override
            public Boolean call(String s)
            {
                return !TextUtils.isEmpty(s);
            }
        }).map(new Func1<String, Observable<String>>()
        {
            @Override
            public Observable<String> call(String s)
            {
                //拿到 要上传的数据

                return getStringObservable(s, "InsertExamine");
            }
        }).doOnNext(new Action1<Observable<String>>()
        {
            @Override
            public void call(Observable<String> stringObservable)
            {
                addSubscribe(subChainWithCallBack(stringObservable, BaseModel.class, callback));
            }
        }).subscribeOn(Schedulers.io()).subscribe();
    }

    /**
     * 上传所有的图片到服务器,并拿到地址放入 数据中
     */
    private Observable<String> upEveryImg(final CheckItemModel itemModel)
    {


        //          Observable.merge(upApplyImgs(itemModel), upModifyImgs(itemModel), upRemarks(itemModel));
        return null;
    }


    private Observable<CheckItemModel> upRemarks(final CheckItemModel itemModel)
    {
        Observable<String> evidenceObservable = _UploadImageOne(itemModel.getEvidence())
                .doOnNext(new Action1<String>()
                {
                    @Override
                    public void call(String s)
                    {
                        itemModel.setEvidence(s);
                    }
                });
        final Observable<String> remarkObservable2 = _UploadImageOne(itemModel.getRemark2())
                .doOnNext(new Action1<String>()
                {
                    @Override
                    public void call(String s)
                    {
                        itemModel.setRemark2(s);
                    }
                }).map(new Func1<String, String>()
                {
                    @Override
                    public String call(String s)
                    {
                        return "FINISHED";
                    }
                });
        final Observable<String> remarkObservable = _UploadImageOne(itemModel.getRemark())
                .doOnNext(new Action1<String>()
                {
                    @Override
                    public void call(String s)
                    {
                        itemModel.setRemark(s);
                    }
                });

        return Observable.concat(evidenceObservable, remarkObservable, remarkObservable2)
                .filter(new Func1<String, Boolean>()
                {
                    @Override
                    public Boolean call(String s)
                    {
                        return TextUtils.equals(s, "FINISHED");
                    }
                }).map(new Func1<String, CheckItemModel>()
                {
                    @Override
                    public CheckItemModel call(String s)
                    {
                        return itemModel;
                    }
                });

        //        return evidenceObservable.map(new Func1<String, Observable<String>>() {
        //            @Override
        //            public Observable<String> call(String s) {
        //
        //                return remarkObservable;
        //            }
        //        }).map(new Func1<Observable<String>, Observable<String>>() {
        //            @Override
        //            public Observable<String> call(Observable<String> stringObservable) {
        //
        //                return remarkObservable;
        //            }
        //        }).map(new Func1<Observable<String>, CheckItemModel>() {
        //            @Override
        //            public CheckItemModel call(Observable<String> stringObservable) {
        //                return itemModel;
        //            }
        //        });

    }

    private Observable<String> upEvery(final CheckItemModel itemModel)
    {

        _UploadImageOne(itemModel.getEvidence()).doOnNext(new Action1<String>()
        {
            @Override
            public void call(String s)
            {
                itemModel.setEvidence(s);
            }
        }).map(new Func1<String, Observable<String>>()
        {
            @Override
            public Observable<String> call(String s)
            {
                return _UploadImageOne(itemModel.getRemark())
                        .doOnNext(new Action1<String>()
                        {
                            @Override
                            public void call(String s)
                            {
                                itemModel.setRemark(s);
                            }
                        });
            }
        }).map(new Func1<Observable<String>, Observable<String>>()
        {
            @Override
            public Observable<String> call(Observable<String> stringObservable)
            {
                return _UploadImageOne(itemModel.getRemark2()).doOnNext(new Action1<String>()
                {
                    @Override
                    public void call(String s)
                    {
                        itemModel.setRemark2(s);
                    }
                });
            }
        }).map(new Func1<Observable<String>, Observable<DangerModel>>()
        {
            @Override
            public Observable<DangerModel> call(Observable<String> stringObservable)
            {
                return Observable.from(itemModel.getDangers())
                        .filter(new Func1<DangerModel, Boolean>()
                        {
                            @Override
                            public Boolean call(DangerModel dangerModel)
                            {
                                return dangerModel != null && (
                                        dangerModel.getBefore_Imgs().size() > 1
                                                || dangerModel.getApplying_Imgs().size() > 1 );
                            }
                        });
            }
        }).switchMap(new Func1<Observable<DangerModel>, Observable<?>>()
        {
            @Override
            public Observable<?> call(Observable<DangerModel> dangerModelObservable)
            {
                return null;
            }
        });
        return null;
    }

    private Observable<CheckItemModel> upModifyImgs(final CheckItemModel itemModel)
    {
        return Observable.from(itemModel.getDangers())
                .switchMap(new Func1<DangerModel, Observable<DangerModel.BeforeImgsEntity>>()
                {
                    @Override
                    public Observable<DangerModel.BeforeImgsEntity> call(DangerModel dangerModel)
                    {

                        List<DangerModel.BeforeImgsEntity> before_imgs = dangerModel
                                .getBefore_Imgs();
                        if ( before_imgs == null )
                        {
                            before_imgs = new ArrayList<>();
                            before_imgs.add(new DangerModel.BeforeImgsEntity());
                        }
                        return Observable.from(before_imgs);
                    }
                }).filter(new Func1<DangerModel.BeforeImgsEntity, Boolean>()
                {
                    @Override
                    public Boolean call(DangerModel.BeforeImgsEntity beforeImgsEntity)
                    {
                        return beforeImgsEntity != null;
                    }
                }).switchMap(new Func1<DangerModel.BeforeImgsEntity, Observable<String>>()
                {
                    @Override
                    public Observable<String> call(final DangerModel.BeforeImgsEntity o)
                    {
                        /**
                         * 上传修改前的图片到服务端并 更新到 数据库
                         */
                        return _UploadImageOne(o.getImg()).doOnNext(new Action1<String>()
                        {
                            @Override
                            public void call(String s)
                            {
                                o.setImg(s);
                            }
                        });
                    }
                }).toList().map(new Func1<List<String>, CheckItemModel>()
                {
                    @Override
                    public CheckItemModel call(List<String> s)
                    {
                        return itemModel;
                    }
                });
    }

    private Observable<CheckItemModel> upApplyImgs(final CheckItemModel model)
    {

        return Observable.from(model.getDangers())
                .switchMap(new Func1<DangerModel, Observable<DangerModel.BeforeImgsEntity>>()
                {
                    @Override
                    public Observable<DangerModel.BeforeImgsEntity> call(DangerModel dangerModel)
                    {
                        List<DangerModel.BeforeImgsEntity> applying_imgs = dangerModel
                                .getApplying_Imgs();
                        if ( applying_imgs == null )
                        {
                            applying_imgs = new ArrayList<>();
                            applying_imgs.add(new DangerModel.BeforeImgsEntity());
                        }
                        return Observable.from(applying_imgs);
                    }
                }).filter(new Func1<DangerModel.BeforeImgsEntity, Boolean>()
                {
                    @Override
                    public Boolean call(DangerModel.BeforeImgsEntity beforeImgsEntity)
                    {
                        return beforeImgsEntity != null;
                    }
                }).switchMap(new Func1<DangerModel.BeforeImgsEntity, Observable<String>>()
                {
                    @Override
                    public Observable<String> call(final DangerModel.BeforeImgsEntity o)
                    {
                        return _UploadImageOne(o.getImg()).doOnNext(new Action1<String>()
                        {
                            @Override
                            public void call(String s)
                            {
                                o.setImg(s);
                                System.out.println("ModifyActionRepository.call == " + s);
                            }
                        });
                    }
                }).toList().map(new Func1<List<String>, CheckItemModel>()
                {
                    @Override
                    public CheckItemModel call(List<String> s)
                    {
                        return model;
                    }
                });
    }
}
